/*
 *  PhotoBoothController.cpp
 *  UseYourHeadApp001
 *
 *  Created by Arne Boon on 5/26/11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */

#include "PhotoBoothController.h"

//--------------------------------------------------------------
PhotoBoothController::PhotoBoothController() {

    cout << "---constructor---PhotoBoothController---" << endl;

    }

//--------------------------------------------------------------
PhotoBoothController::~PhotoBoothController() {

    cout << "---destructor---PhotoBoothController---" << endl;

    }


//--------------------------------------------------------------
void PhotoBoothController::setup() {

    cout << "--setup--" << endl;
    ofEnableAlphaBlending();
    ///------start photobooth
    camWidth = 640;
    camHeight = 480;
    vidGrabber.setVerbose(true);
    vidGrabber.initGrabber(camWidth, camHeight);
    videoMirror = new unsigned char[camWidth*camHeight*3];
    mirrorTexture.allocate(camWidth, camHeight, GL_RGB);

    ofBackground(200,200,200);
    totalPixels = GRABBED_VID_WIDTH * GRABBED_VID_HEIGHT * 4;
    totalPixelsTop = GRABBED_VID_WIDTH * GRABBED_VID_TOP * 4;

    top.allocate(GRABBED_VID_WIDTH, GRABBED_VID_TOP, GL_RGBA);
    bottom.allocate(GRABBED_VID_WIDTH, GRABBED_VID_HEIGHT, GL_RGBA);
    snapShotTaken = false;
    offsetMouth = 0;
    mouthOpen = false;
    animation = false;
    scale = 2;
    setScale(scale);
    outputImageBottom.allocate(camWidth, camHeight, OF_IMAGE_COLOR_ALPHA);

    }

//--------------------------------------------------------------
void PhotoBoothController::update() {

    mirrorVideo();
    setHead();
    moveMouth();

    }

//--------------------------------------------------------------
void PhotoBoothController::draw() {

    ofSetColor(255,255,255);
    //snapShot.draw(0, 0);
    if(animation == false) {
        mirrorTexture.draw(0, 0);
        ofLine(0, GRABBED_VID_TOP, GRABBED_VID_WIDTH, GRABBED_VID_TOP);
        }

    if(animation == true) {
        top.draw(0, 0, headX, headTopY);
        bottom.draw(0, headTopY + offsetMouth, headX, headBottomY);
        }unsigned char * snapShotPixels;

    }

//--------------------------------------------------------------
void PhotoBoothController::keyPressed(int key) {

    if (key == ' ' || key == 'f') {
        snapShot.grabScreen(0, 0, GRABBED_VID_WIDTH, GRABBED_VID_HEIGHT);
        snapShotTaken = true;
        animation = true;
        }

    }


//--------------------------------------------------------------
void PhotoBoothController::setScale(int scale) {

    headX = GRABBED_VID_WIDTH / scale;
    headTopY = GRABBED_VID_TOP / scale;
    headBottomY = GRABBED_VID_BOTTOM / scale;
    }


//--------------------------------------------------------------
void PhotoBoothController::setHead() {
    if (snapShotTaken == true) {
        snapShot.setImageType(OF_IMAGE_COLOR_ALPHA);
        snapShotPixels = snapShot.getPixels();

        for (int i = 0; i < totalPixels; i += 4) {

            if(i <= GRABBED_VID_WIDTH * GRABBED_VID_HEIGHT * 4) {
                 if(snapShotPixels[i]>120&&snapShotPixels[i]<190&&
                        snapShotPixels[i+1]>245&&snapShotPixels[i+1]<256&&
                        snapShotPixels[i+2]>135&&snapShotPixels[i+2]<215) {

                    topPixels[i] = 255;
                    topPixels[i + 1] = 255;
                    topPixels[i + 2] = 255;
                    topPixels[i + 3] = 0;

                    }
                else {
                    topPixels[i] = snapShotPixels[i];
                    topPixels[i + 1] = snapShotPixels[i + 1];
                    topPixels[i + 2] = snapShotPixels[i + 2];
                    topPixels[i + 3] = 255;
                    }

                }

            if (i >= GRABBED_VID_WIDTH * GRABBED_VID_BOTTOM * 4) {

                if(snapShotPixels[i]>120&&snapShotPixels[i]<190&&
                        snapShotPixels[i+1]>245&&snapShotPixels[i+1]<256&&
                        snapShotPixels[i+2]>135&&snapShotPixels[i+2]<215) {

                    dataPixels[i - totalPixelsTop] = 255;
                    dataPixels[i + 1 - totalPixelsTop] = 255;
                    dataPixels[i + 2 - totalPixelsTop] = 255;
                    dataPixels[i + 3 - totalPixelsTop] = 0;

                    }
                else {
                    dataPixels[i - totalPixelsTop] = snapShotPixels[i];;
                    dataPixels[i + 1 - totalPixelsTop] = snapShotPixels[i + 1];
                    dataPixels[i + 2 - totalPixelsTop] = snapShotPixels[i + 2];
                    dataPixels[i + 3 - totalPixelsTop] = 255;
                    }
                }
            }


        top.loadData(topPixels, GRABBED_VID_WIDTH, GRABBED_VID_TOP, GL_RGBA);
        bottom.loadData(dataPixels, GRABBED_VID_WIDTH, GRABBED_VID_BOTTOM, GL_RGBA);

        outputImageTop.setFromPixels(topPixels,camWidth,GRABBED_VID_TOP,OF_IMAGE_COLOR_ALPHA);
        outputImageTop.saveImage("topImage.png");
        outputImageBottom.setFromPixels(dataPixels,camWidth,GRABBED_VID_BOTTOM,OF_IMAGE_COLOR_ALPHA);
        outputImageBottom.saveImage("bottomImage.png");
        snapShotTaken = false;
        }
    }

//--------------------------------------------------------------
void PhotoBoothController::moveMouth() {
    if (mouthOpen == false) {
        offsetMouth += 1.5;
        if (offsetMouth >= 10) {
            mouthOpen = true;

            }
        }
    else {
        offsetMouth -= 1.5;
        if (offsetMouth <= 0) {

            mouthOpen = false;
            }
        }cout << "sjdhashdah" << endl;
    }


//--------------------------------------------------------------
void PhotoBoothController::mirrorVideo() {
    vidGrabber.grabFrame();
    if (vidGrabber.isFrameNew()) {
        unsigned char * pixels = vidGrabber.getPixels();
        for (int i = 0; i < camHeight; i++) {
            for (int j = 0; j < camWidth*3; j+=3) {
                // pixel number
                int pix1 = (i*camWidth*3) + j;
                int pix2 = (i*camWidth*3) + (j+1);
                int pix3 = (i*camWidth*3) + (j+2);
                // mirror pixel number
                int mir1 = (i*camWidth*3)+1 * (camWidth*3 - j-3);
                int mir2 = (i*camWidth*3)+1 * (camWidth*3 - j-2);
                int mir3 = (i*camWidth*3)+1 * (camWidth*3 - j-1);
                // swap pixels
                videoMirror[pix1] = pixels[mir1];
                videoMirror[pix2] = pixels[mir2];
                videoMirror[pix3] = pixels[mir3];
                }
            }
        //mirrorTexture.loadData(videoMirror, camWidth, camHeight, GL_RGB);
        mirrorTexture.loadData(pixels, camWidth, camHeight, GL_RGB);
        }
    }

